"""
逻辑计划生成器
将语义分析的四元式中间代码转换为逻辑执行计划
"""

from typing import List, Dict, Any, Optional, Tuple
from dataclasses import dataclass
from enum import Enum

# 导入SqlCompiler的类型
import sys
import os
from SemanticAnalysis import Quadruple, SymbolTableEntry

# 导入Engine的类型
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
from ExecutionEngine.query_plan import QueryPlan, PlanNode, PlanBuilder
from ExecutionEngine.types import OperatorType, JoinType, AggregateFunction, SortDirection


class LogicalOperatorType(Enum):
    """逻辑操作符类型"""
    SCAN = "scan"
    PROJECT = "project"
    FILTER = "filter"
    JOIN = "join"
    AGGREGATE = "aggregate"
    SORT = "sort"
    LIMIT = "limit"
    INSERT = "insert"
    CREATE_TABLE = "create_table"
    DELETE = "delete"
    UPDATE = "update"
    # Database级DDL操作
    CREATE_DATABASE = "create_database"
    DROP_DATABASE = "drop_database"
    USE_DATABASE = "use_database"
    LIST_DATABASES = "list_databases"
    # 集合操作
    UNION = "union"
    INTERSECT = "intersect"
    EXCEPT = "except"
    # 权限管理
    GRANT = "grant"
    # 用户管理
    CREATE_USER = "create_user"
    DROP_USER = "drop_user"


@dataclass
class LogicalNode:
    """逻辑计划节点"""
    operator_type: LogicalOperatorType # 操作符类型
    properties: Dict[str, Any] # 属性
    children: List['LogicalNode'] = None # 子节点
    node_id: str = "" # 节点ID
    
    def __post_init__(self):
        if self.children is None:
            self.children = []
        if not self.node_id:
            self.node_id = f"{self.operator_type.value}_{id(self)}"


class LogicalPlanGenerator:
    """逻辑计划生成器"""
    
    def __init__(self):
        self.temp_counter = 0 # 临时计数器
        self.current_tables = {}  # 当前查询涉及的表
        self.column_mapping = {}  # 列到表的映射
    
    def generate_logical_plan(self, quadruples: List[Quadruple], 
                            symbol_table: Dict[str, SymbolTableEntry]) -> LogicalNode:
        """
        从四元式生成逻辑执行计划
        
        Args:
            quadruples: 语义分析生成的四元式列表
            symbol_table: 符号表
            
        Returns:
            LogicalNode: 逻辑执行计划的根节点
        """
        if not quadruples:
            raise ValueError("Empty quadruples list")
        
        # 分析四元式，确定查询类型
        query_type = self._determine_query_type(quadruples)
        
        if query_type == "SELECT":
            return self._generate_select_plan(quadruples, symbol_table)
        elif query_type == "CREATE":
            return self._generate_create_plan(quadruples, symbol_table)
        elif query_type == "INSERT":
            return self._generate_insert_plan(quadruples, symbol_table)
        elif query_type == "DELETE":
            return self._generate_delete_plan(quadruples, symbol_table)
        elif query_type == "UPDATE":
            return self._generate_update_plan(quadruples, symbol_table)
        elif query_type == "GRANT":
            return self._generate_grant_plan(quadruples, symbol_table)
        elif query_type == "UNION" or query_type == "INTERSECT" or query_type == "EXCEPT":
            return self._generate_set_operation_plan(quadruples, symbol_table, query_type)
        elif query_type == "CREATE_DATABASE":
            return self._generate_create_database_plan(quadruples, symbol_table)
        elif query_type == "DROP_DATABASE":
            return self._generate_drop_database_plan(quadruples, symbol_table)
        elif query_type == "USE":
            return self._generate_use_database_plan(quadruples, symbol_table)
        elif query_type == "LIST_DATABASES":
            return self._generate_list_databases_plan(quadruples, symbol_table)
        elif query_type == "CREATE_USER":
            return self._generate_create_user_plan(quadruples, symbol_table)
        elif query_type == "DROP_USER":
            return self._generate_drop_user_plan(quadruples, symbol_table)
        else:
            raise ValueError(f"Unsupported query type: {query_type}")
    
    def _determine_query_type(self, quadruples: List[Quadruple]) -> str:
        """确定查询类型"""
        # 检查是否包含集合操作
        for quad in quadruples:
            if quad.op == "UNION":
                return "UNION"
            elif quad.op == "INTERSECT":
                return "INTERSECT"
            elif quad.op == "EXCEPT":
                return "EXCEPT"
        
        # 检查其他操作类型
        for quad in quadruples:
            if quad.op == "SELECT":
                return "SELECT"
            elif quad.op == "CREATE":
                return "CREATE"
            elif quad.op == "CREATE_USER":
                return "CREATE_USER"
            elif quad.op == "DROP_USER":
                return "DROP_USER"
            elif quad.op == "CREATE_DATABASE":
                return "CREATE_DATABASE"
            elif quad.op == "DROP_DATABASE":
                return "DROP_DATABASE"
            elif quad.op == "USE":
                return "USE"
            elif quad.op == "LIST_DATABASES":
                return "LIST_DATABASES"
            elif quad.op == "INSERT":
                return "INSERT"
            elif quad.op == "DELETE":
                return "DELETE"
            elif quad.op == "UPDATE":
                return "UPDATE"
            elif quad.op == "GRANT":
                return "GRANT"
        return "UNKNOWN"
    
    def _generate_select_plan(self, quadruples: List[Quadruple], 
                            symbol_table: Dict[str, SymbolTableEntry]) -> LogicalNode:
        """生成SELECT查询的逻辑计划"""
        
        # 分析四元式，提取查询组件
        from_tables = []
        select_columns = []
        where_conditions = []
        join_operations = []  # 存储JOIN操作
        aggregate_operations = []  # 存储聚合操作
        group_by_columns = []  # 存储GROUP BY列
        order_by_specs = []
        limit_count = None
        logical_operations = []  # 存储AND/OR操作
        
        for quad in quadruples:
            if quad.op == "FROM":
                from_tables.append(quad.arg1)
            elif quad.op == "SELECT":
                column_spec = quad.arg1
                # 处理别名，格式: "column AS alias" 或 "column"
                if ' AS ' in column_spec:
                    parts = column_spec.split(' AS ', 1)
                    if len(parts) == 2:
                        column_name = parts[0].strip()
                        alias = parts[1].strip()
                        select_columns.append({
                            'column': column_name,
                            'alias': alias,
                            'expression': column_spec
                        })
                    else:
                        select_columns.append({
                            'column': column_spec,
                            'alias': None,
                            'expression': column_spec
                        })
                else:
                    select_columns.append({
                        'column': column_spec,
                        'alias': None,
                        'expression': column_spec
                    })
            elif quad.op == "AGGREGATE":
                # 解析聚合四元式，格式: "function:column" 或 "function:*"
                aggregate_spec = quad.arg1
                if ':' in aggregate_spec:
                    parts = aggregate_spec.split(':', 1)
                    function_name = parts[0]
                    column = parts[1]
                    # 为聚合函数设置正确的别名
                    alias = f"{function_name}({column})"
                    aggregate_operations.append({
                        'function': function_name,
                        'column': column,
                        'result': quad.result,
                        'alias': alias
                    })
                else:
                    # 兼容性处理，如果没有冒号，假设是COUNT(*)
                    alias = f"{aggregate_spec}(*)"
                    aggregate_operations.append({
                        'function': aggregate_spec,
                        'column': '*',
                        'result': quad.result,
                        'alias': alias
                    })
            elif quad.op == "JOIN":
                # 解析JOIN四元式，格式: join_type:table:condition
                join_spec = quad.arg1
                if ':' in join_spec:
                    parts = join_spec.split(':', 2)
                    if len(parts) >= 2:
                        join_type = parts[0]
                        right_table = parts[1]
                        condition = parts[2] if len(parts) > 2 else ""
                        
                        # 从condition中提取别名信息
                        # 例如: "u.id = o.user_id" -> 左表别名=u, 右表别名=o
                        left_alias = None
                        right_alias = None
                        if "=" in condition:
                            left_expr, right_expr = condition.split("=", 1)
                            left_expr = left_expr.strip()
                            right_expr = right_expr.strip()
                            
                            if "." in left_expr:
                                left_alias = left_expr.split(".")[0]
                            if "." in right_expr:
                                right_alias = right_expr.split(".")[0]
                        
                        join_operations.append({
                            'type': join_type,
                            'right_table': right_table,
                            'condition': condition,
                            'left_table': quad.arg2,
                            'result': quad.result,
                            'left_alias': left_alias,
                            'right_alias': right_alias
                        })
            elif quad.op in [">", "<", "=", ">=", "<=", "!=", "LIKE"]:
                where_conditions.append({
                    'column': quad.arg1,# 列
                    'operator': quad.op,# 操作符
                    'value': quad.arg2, # 值
                    'temp_var': quad.result # 临时变量
                })
            elif quad.op in ["AND", "OR"]:
                logical_operations.append({
                    'operator': quad.op,
                    'left': quad.arg1,
                    'right': quad.arg2,
                    'temp_var': quad.result
                })
            elif quad.op == "ORDER":
                # 解析ORDER BY规范，格式: "col1:ASC,col2:DESC"
                order_spec = quad.arg1
                if order_spec:
                    for spec in order_spec.split(','):
                        if ':' in spec:
                            col, direction = spec.split(':', 1)
                            order_by_specs.append({
                                'column': col.strip(),
                                'direction': direction.strip().upper()
                            })
                        else:
                            order_by_specs.append({
                                'column': spec.strip(),
                                'direction': 'ASC'
                            })
            elif quad.op == "LIMIT":
                limit_count = int(quad.arg1)
            elif quad.op == "GROUP":
                # 解析GROUP BY四元式，格式: "col1,col2,col3"
                if quad.arg1:
                    group_by_columns = [col.strip() for col in quad.arg1.split(',')]
        
        # 构建逻辑计划树
        # 1. 扫描节点（最底层）
        if not from_tables:
            raise ValueError("No FROM clause found")
        
        # 创建左表扫描节点
        # 尝试从JOIN操作中获取左表别名
        left_alias = from_tables[0]
        if join_operations and join_operations[0].get('left_alias'):
            left_alias = join_operations[0]['left_alias']
        
        left_scan_node = LogicalNode(
            operator_type=LogicalOperatorType.SCAN,
            properties={
                'table_name': from_tables[0],
                'alias': left_alias
            }
        )
        
        current_node = left_scan_node
        
        # 2. 处理JOIN操作
        if join_operations:
            for join_op in join_operations:
                # 创建右表扫描节点
                right_alias = join_op.get('right_alias') or join_op['right_table']
                right_scan_node = LogicalNode(
                    operator_type=LogicalOperatorType.SCAN,
                    properties={
                        'table_name': join_op['right_table'],
                        'alias': right_alias
                    }
                )
                
                # 转换JOIN类型
                join_type_mapping = {
                    'INNER': 'INNER',
                    'LEFT': 'LEFT',
                    'RIGHT': 'RIGHT',
                    'FULL': 'FULL'
                }
                
                # 创建JOIN节点
                join_node = LogicalNode(
                    operator_type=LogicalOperatorType.JOIN,
                    properties={
                        'join_type': join_type_mapping.get(join_op['type'], 'INNER'),
                        'join_condition': join_op['condition']
                    },
                    children=[current_node, right_scan_node]
                )
                current_node = join_node
        
        # 3. 过滤节点（WHERE条件）- 只处理非JOIN条件
        if where_conditions or logical_operations:
            # 过滤掉已经在JOIN条件中处理的条件
            non_join_where_conditions = []
            for condition in where_conditions:
                # 简单检查：如果条件不是JOIN条件的一部分，则添加到WHERE过滤中
                is_join_condition = False
                for join_op in join_operations:
                    if (condition['column'] in join_op['condition'] and 
                        condition['value'] in join_op['condition']):
                        is_join_condition = True
                        break
                if not is_join_condition:
                    non_join_where_conditions.append(condition)
            
            # 如果有逻辑操作符，需要构建复合过滤条件
            if logical_operations and non_join_where_conditions:
                # 构建复合过滤表达式
                filter_predicate = self._build_composite_filter(non_join_where_conditions, logical_operations)
                filter_node = LogicalNode(
                    operator_type=LogicalOperatorType.FILTER,
                    properties={
                        'predicate': filter_predicate
                    },
                    children=[current_node]
                )
                current_node = filter_node
            elif non_join_where_conditions:
                # 简单条件，逐个添加过滤节点
                for condition in non_join_where_conditions:
                    filter_node = LogicalNode(
                        operator_type=LogicalOperatorType.FILTER,
                        properties={
                            'predicate': f"{condition['column']} {condition['operator']} {condition['value']}"
                        },
                        children=[current_node]
                    )
                    current_node = filter_node
        
        # 4. 排序节点（ORDER BY）
        if order_by_specs:
            sort_node = LogicalNode(
                operator_type=LogicalOperatorType.SORT,
                properties={
                    'order_by': order_by_specs
                },
                children=[current_node]
            )
            current_node = sort_node
        
        # 5. 聚合节点（AGGREGATE）
        if aggregate_operations:
            aggregate_node = LogicalNode(
                operator_type=LogicalOperatorType.AGGREGATE,
                properties={
                    'aggregates': aggregate_operations,
                    'group_by': group_by_columns  # 支持GROUP BY
                },
                children=[current_node]
            )
            current_node = aggregate_node
        
        # 6. 限制节点（LIMIT）
        if limit_count is not None:
            limit_node = LogicalNode(
                operator_type=LogicalOperatorType.LIMIT,
                properties={
                    'count': limit_count
                },
                children=[current_node]
            )
            current_node = limit_node
        
        # 7. 投影节点（SELECT列）
        if select_columns:
            project_node = LogicalNode(
                operator_type=LogicalOperatorType.PROJECT,
                properties={
                    'columns': select_columns
                },
                children=[current_node]
            )
            current_node = project_node
        
        return current_node
    
    def _build_composite_filter(self, where_conditions: List[Dict], logical_operations: List[Dict]) -> str:
        """构建复合过滤表达式"""
        if not logical_operations:
            # 如果没有逻辑操作符，就是简单的单条件
            if where_conditions:
                condition = where_conditions[0]
                return f"{condition['column']} {condition['operator']} {condition['value']}"
            return ""
        
        # 构建条件映射：从临时变量到实际条件
        condition_map = {}
        for condition in where_conditions:
            temp_var = condition['temp_var']
            predicate = f"{condition['column']} {condition['operator']} {condition['value']}"
            condition_map[temp_var] = predicate
        
        # 处理逻辑操作符，构建复合表达式
        # 这里需要根据四元式的结构来重建逻辑表达式
        final_expression = ""
        
        # 查找最后的逻辑操作结果（通常是WHERE四元式使用的）
        for quad_list in [logical_operations]:
            for logical_op in quad_list:
                left_expr = logical_op['left']
                right_expr = logical_op['right']
                operator = logical_op['operator']
                
                # 替换临时变量为实际条件
                for temp_var, condition in condition_map.items():
                    if temp_var in left_expr:
                        left_expr = left_expr.replace(temp_var, f"({condition})")
                    if temp_var in right_expr:
                        right_expr = right_expr.replace(temp_var, f"({condition})")
                
                # 如果左右表达式还包含逻辑表达式，需要进一步解析
                # 简化处理：直接使用原始表达式
                if "=" in left_expr or ">" in left_expr or "<" in left_expr or "LIKE" in left_expr:
                    # 已经是基本条件
                    pass
                else:
                    # 可能是嵌套的逻辑表达式，保持原样
                    pass
                
                final_expression = f"({left_expr} {operator} {right_expr})"
        
        return final_expression if final_expression else (condition_map[list(condition_map.keys())[0]] if condition_map else "")
    
    def _generate_create_plan(self, quadruples: List[Quadruple], 
                            symbol_table: Dict[str, SymbolTableEntry]) -> LogicalNode:
        """生成CREATE TABLE的逻辑计划"""
        
        table_name = ""
        columns = []
        
        for quad in quadruples:
            if quad.op == "CREATE":
                table_name = quad.arg1
            elif quad.op == "COLUMN":
                columns.append({
                    'name': quad.arg1,
                    'type': quad.arg2
                })
        
        create_node = LogicalNode(
            operator_type=LogicalOperatorType.CREATE_TABLE,
            properties={
                'table_name': table_name,
                'columns': columns
            }
        )
        
        return create_node
    
    def _generate_insert_plan(self, quadruples: List[Quadruple], 
                            symbol_table: Dict[str, SymbolTableEntry]) -> LogicalNode:
        """生成INSERT的逻辑计划"""
        
        table_name = ""
        values = []
        
        for quad in quadruples:
            if quad.op == "INSERT":
                table_name = quad.arg1
            elif quad.op == "=":
                # 新格式支持 T1.column_name 或 T1.value_index
                column_info = quad.result.split('.')[1] if '.' in quad.result else quad.result
                values.append({
                    'column': column_info,
                    'value': quad.arg1
                })
        
        insert_node = LogicalNode(
            operator_type=LogicalOperatorType.INSERT,
            properties={
                'table_name': table_name,
                'values': values
            }
        )
        
        return insert_node
    
    def _generate_delete_plan(self, quadruples: List[Quadruple], 
                            symbol_table: Dict[str, SymbolTableEntry]) -> LogicalNode:
        """生成DELETE的逻辑计划"""
        
        table_name = ""
        where_conditions = []
        
        for quad in quadruples:
            if quad.op == "FROM":
                table_name = quad.arg1
            elif quad.op in [">", "<", "=", ">=", "<=", "!="]:
                where_conditions.append({
                    'column': quad.arg1,
                    'operator': quad.op,
                    'value': quad.arg2
                })
        
        # 构建删除计划：扫描 -> 过滤 -> 删除
        scan_node = LogicalNode(
            operator_type=LogicalOperatorType.SCAN,
            properties={
                'table_name': table_name
            }
        )
        
        current_node = scan_node
        
        # 添加过滤条件
        if where_conditions:
            for condition in where_conditions:
                filter_node = LogicalNode(
                    operator_type=LogicalOperatorType.FILTER,
                    properties={
                        'predicate': f"{condition['column']} {condition['operator']} {condition['value']}"
                    },
                    children=[current_node]
                )
                current_node = filter_node
        
        # 删除节点
        delete_node = LogicalNode(
            operator_type=LogicalOperatorType.DELETE,
            properties={
                'table_name': table_name
            },
            children=[current_node]
        )
        
        return delete_node
    
    def print_logical_plan(self, node: LogicalNode, indent: int = 0):
        """打印逻辑计划树"""
        prefix = "  " * indent + "└─ " if indent > 0 else ""
        print(f"{prefix}{node.operator_type.value.upper()}")
        
        # 打印属性
        for key, value in node.properties.items():
            print(f"{prefix}   {key}: {value}")
        
        # 递归打印子节点
        for child in node.children:
            self.print_logical_plan(child, indent + 1)
    
    def _generate_update_plan(self, quadruples: List[Quadruple], 
                            symbol_table: Dict[str, SymbolTableEntry]) -> LogicalNode:
        """生成UPDATE的逻辑计划"""
        
        table_name = ""
        set_clauses = []
        where_conditions = []
        
        for quad in quadruples:
            if quad.op == "UPDATE":
                table_name = quad.arg1
            elif quad.op == "SET":
                # 解析SET子句，格式为 "column=value" 或 "column=expression"
                set_expr = quad.arg1
                if '=' in set_expr:
                    parts = set_expr.split('=', 1)  # 只分割第一个等号
                    if len(parts) == 2:
                        column = parts[0].strip()
                        value_expr = parts[1].strip()
                        
                        # 检查是否是算术表达式
                        if any(op in value_expr for op in ['+', '-', '*', '/']):
                            # 保持表达式格式，让执行引擎处理
                            processed_value = value_expr
                        else:
                            # 尝试转换为数字
                            try:
                                processed_value = int(value_expr)
                            except ValueError:
                                try:
                                    processed_value = float(value_expr)
                                except ValueError:
                                    # 移除引号
                                    processed_value = value_expr.strip("'\"")
                        
                        set_clauses.append({
                            'column': column,
                            'value': processed_value,
                            'is_expression': any(op in value_expr for op in ['+', '-', '*', '/'])
                        })
            elif quad.op in ["=", ">", "<", ">=", "<=", "!="]:
                where_conditions.append({
                    'column': quad.arg1,
                    'operator': quad.op,
                    'value': quad.arg2
                })
        
        # 创建表扫描节点
        scan_node = LogicalNode(
            operator_type=LogicalOperatorType.SCAN,
            properties={
                'table_name': table_name
            }
        )
        
        current_node = scan_node
        
        # 添加WHERE过滤条件
        if where_conditions:
            for condition in where_conditions:
                filter_node = LogicalNode(
                    operator_type=LogicalOperatorType.FILTER,
                    properties={
                        'predicate': f"{condition['column']} {condition['operator']} {condition['value']}"
                    },
                    children=[current_node]
                )
                current_node = filter_node
        
        # 创建UPDATE节点
        update_node = LogicalNode(
            operator_type=LogicalOperatorType.UPDATE,
            properties={
                'table_name': table_name,
                'set_clauses': set_clauses,
                'where_condition': ' AND '.join([f"{c['column']} {c['operator']} {c['value']}" for c in where_conditions]) if where_conditions else None
            },
            children=[current_node]
        )
        
        return update_node
    
    def _generate_grant_plan(self, quadruples: List[Quadruple], 
                           symbol_table: Dict[str, SymbolTableEntry]) -> LogicalNode:
        """生成GRANT的逻辑计划"""
        
        grant_info = {}
        for quad in quadruples:
            if quad.op == "GRANT":
                # 解析GRANT四元式，格式: privileges:object_type:object_name:grantees
                grant_spec = quad.arg1
                parts = grant_spec.split(':', 4)
                if len(parts) >= 4:
                    grant_info['privileges'] = parts[0]
                    grant_info['object_type'] = parts[1]
                    grant_info['object_name'] = parts[2]
                    grant_info['grantees'] = parts[3]
                    if len(parts) > 4:
                        grant_info['grant_option'] = parts[4]
        
        grant_node = LogicalNode(
            operator_type=LogicalOperatorType.GRANT,
            properties=grant_info
        )
        
        return grant_node
    
    def _generate_set_operation_plan(self, quadruples: List[Quadruple], 
                                   symbol_table: Dict[str, SymbolTableEntry],
                                   operation_type: str) -> LogicalNode:
        """生成集合操作的逻辑计划"""
        
        # 解析UNION四元式并构建左右子查询
        left_query_quadruples = []
        right_query_quadruples = []
        left_temp_var = None
        right_temp_var = None
        distinct = True
        
        # 找到UNION四元式
        union_quad = None
        for quad in quadruples:
            if quad.op == operation_type:
                union_quad = quad
                break
        
        if not union_quad:
            raise ValueError(f"No {operation_type} operation found")
        
        # 解析UNION四元式，格式: "UNION:T2:T4"
        operation_spec = union_quad.arg1
        if operation_spec.startswith(f"{operation_type}:"):
            spec_parts = operation_spec.split(':', 2)
            if len(spec_parts) >= 3:
                left_temp_var = spec_parts[1]  # T2
                right_temp_var = spec_parts[2]  # T4
        
        # 分离左右子查询的四元式
        # 需要找到SELECT四元式对应的FROM四元式
        left_from_temp = None
        right_from_temp = None
        
        # 先找到SELECT四元式使用的表引用
        for quad in quadruples:
            if quad.op == "SELECT" and quad.result == left_temp_var:
                left_from_temp = quad.arg2  # arg2是表引用，如T1
                left_query_quadruples.append(quad)
            elif quad.op == "SELECT" and quad.result == right_temp_var:
                right_from_temp = quad.arg2  # arg2是表引用，如T3
                right_query_quadruples.append(quad)
        
        # 再找到对应的FROM四元式
        for quad in quadruples:
            if quad.op == "FROM":
                if quad.result == left_from_temp:
                    left_query_quadruples.append(quad)
                elif quad.result == right_from_temp:
                    right_query_quadruples.append(quad)
        
        # 生成左子查询计划
        left_plan = self._generate_simple_select_plan(left_query_quadruples, symbol_table)
        
        # 生成右子查询计划  
        right_plan = self._generate_simple_select_plan(right_query_quadruples, symbol_table)
        
        # 创建集合操作节点
        if operation_type == "UNION":
            op_type = LogicalOperatorType.UNION
        elif operation_type == "INTERSECT":
            op_type = LogicalOperatorType.INTERSECT
        elif operation_type == "EXCEPT":
            op_type = LogicalOperatorType.EXCEPT
        else:
            raise ValueError(f"Unknown set operation: {operation_type}")
        
        set_node = LogicalNode(
            operator_type=op_type,
            properties={
                'distinct': distinct
            },
            children=[left_plan, right_plan]
        )
        
        return set_node
    
    def _generate_simple_select_plan(self, quadruples: List[Quadruple], 
                                   symbol_table: Dict[str, SymbolTableEntry]) -> LogicalNode:
        """生成简单的SELECT计划，用于集合操作的子查询"""
        from_table = None
        select_columns = []
        
        for quad in quadruples:
            if quad.op == "FROM":
                from_table = quad.arg1
            elif quad.op == "SELECT":
                select_columns.append(quad.arg1)
        
        if not from_table:
            raise ValueError("No FROM clause found in subquery")
        
        # 创建扫描节点
        scan_node = LogicalNode(
            operator_type=LogicalOperatorType.SCAN,
            properties={
                'table_name': from_table,
                'alias': from_table
            }
        )
        
        # 创建投影节点
        if select_columns:
            project_node = LogicalNode(
                operator_type=LogicalOperatorType.PROJECT,
                properties={'columns': select_columns},
                children=[scan_node]
            )
            return project_node
        
        return scan_node
    
    def _generate_create_database_plan(self, quadruples: List[Quadruple], 
                                      symbol_table: Dict[str, SymbolTableEntry]) -> LogicalNode:
        """生成CREATE DATABASE的逻辑计划"""
        database_name = None
        charset = "utf8"
        
        # 从四元式中提取数据库名和字符集
        for quad in quadruples:
            if quad.op == "CREATE_DATABASE":
                database_name = quad.arg1
                if quad.arg2 and quad.arg2 != "-":
                    charset = quad.arg2
                break
        
        if not database_name:
            raise ValueError("CREATE DATABASE requires database name")
        
        return LogicalNode(
            operator_type=LogicalOperatorType.CREATE_DATABASE,
            properties={
                "database_name": database_name,
                "charset": charset
            }
        )
    
    def _generate_drop_database_plan(self, quadruples: List[Quadruple], 
                                   symbol_table: Dict[str, SymbolTableEntry]) -> LogicalNode:
        """生成DROP DATABASE的逻辑计划"""
        database_name = None
        force = False
        
        # 从四元式中提取数据库名和选项
        for quad in quadruples:
            if quad.op == "DROP_DATABASE":
                database_name = quad.arg1
                if quad.arg2 and quad.arg2.upper() == "FORCE":
                    force = True
                break
        
        if not database_name:
            raise ValueError("DROP DATABASE requires database name")
        
        return LogicalNode(
            operator_type=LogicalOperatorType.DROP_DATABASE,
            properties={
                "database_name": database_name,
                "force": force
            }
        )
    
    def _generate_use_database_plan(self, quadruples: List[Quadruple], 
                                  symbol_table: Dict[str, SymbolTableEntry]) -> LogicalNode:
        """生成USE DATABASE的逻辑计划"""
        database_name = None
        
        # 从四元式中提取数据库名
        for quad in quadruples:
            if quad.op == "USE":
                database_name = quad.arg1
                break
        
        if not database_name:
            raise ValueError("USE DATABASE requires database name")
        
        return LogicalNode(
            operator_type=LogicalOperatorType.USE_DATABASE,
            properties={
                "database_name": database_name
            }
        )
    
    def _generate_list_databases_plan(self, quadruples: List[Quadruple], 
                                    symbol_table: Dict[str, SymbolTableEntry]) -> LogicalNode:
        """生成LIST DATABASES的逻辑计划"""
        return LogicalNode(
            operator_type=LogicalOperatorType.LIST_DATABASES,
            properties={}
        )
    
    def _generate_create_user_plan(self, quadruples: List[Quadruple], 
                                 symbol_table: Dict[str, SymbolTableEntry]) -> LogicalNode:
        """生成CREATE USER的逻辑计划"""
        username = None
        password = None
        
        # 从四元式中提取用户名和密码
        for quad in quadruples:
            if quad.op == "CREATE_USER":
                username = quad.arg1
                password = quad.arg2 if quad.arg2 != "-" else None
                break
        
        if not username:
            raise ValueError("CREATE USER requires username")
        
        return LogicalNode(
            operator_type=LogicalOperatorType.CREATE_USER,
            properties={
                "username": username,
                "password": password
            }
        )
    
    def _generate_drop_user_plan(self, quadruples: List[Quadruple], 
                               symbol_table: Dict[str, SymbolTableEntry]) -> LogicalNode:
        """生成DROP USER的逻辑计划"""
        username = None
        
        # 从四元式中提取用户名
        for quad in quadruples:
            if quad.op == "DROP_USER":
                username = quad.arg1
                break
        
        if not username:
            raise ValueError("DROP USER requires username")
        
        return LogicalNode(
            operator_type=LogicalOperatorType.DROP_USER,
            properties={
                "username": username
            }
        )


def test_logical_plan_generation():
    """测试逻辑计划生成"""
    print("=" * 60)
    print("逻辑计划生成器测试")
    print("=" * 60)
    
    generator = LogicalPlanGenerator()
    
    # 模拟SELECT查询的四元式
    select_quadruples = [
        Quadruple("FROM", "student", "-", "T1"),
        Quadruple(">", "age", "18", "T2"),
        Quadruple("WHERE", "age > 18", "T1", "T3"),
        Quadruple("SELECT", "id", "T3", "T4"),
        Quadruple("SELECT", "name", "T3", "T5"),
        Quadruple("RESULT", "T5", "-", "-")
    ]
    
    print("输入四元式:")
    for i, quad in enumerate(select_quadruples):
        print(f"  {i}: {quad}")
    
    print("\n生成的逻辑计划:")
    logical_plan = generator._generate_select_plan(select_quadruples, {})
    generator.print_logical_plan(logical_plan)


if __name__ == "__main__":
    test_logical_plan_generation()

